<template>
  <div class="canvas-page f-c">
    <BackPage title="流程图配置" show-back @back="onPageBack" />
    <div class="canvas f-g f-r">
      <div class="menu">
        <el-collapse v-model="activeNames">
          <el-collapse-item name="custom" title="自定义节点">
            <div class="content f-r f-w">
              <div
                :draggable="true"
                class="menu-item"
                @dragstart="onDrag($event,{ name: 'text', text: '双击输入文本', font: { color: '#000'}, rect: { width: 120, height: 50}, data: { type: 'text'}})"
              >
                普通文本
              </div>
            </div>
          </el-collapse-item>
          <el-collapse-item v-for="(item, i) in Tools2" :key="i" :title="item.name" :name="item.stage">
            <div class="content f-r f-w">
              <div
                v-for="(sub, j) in (item.productVoList || []).filter(el => el.display)"
                :key="j"
                :draggable="true"
                class="menu-item"
                @dragstart="onDrag($event, sub)"
              >
                {{ sub.productName }}
              </div>
            </div>
          </el-collapse-item>
          <el-collapse-item v-for="(item, i) in Tools" :key="i" :title="item.name" :name="item.stage">
            <div style="">(必经)</div>
            <div class="content">
              <div
                v-for="(sub, j) in (item.productVoList || []).filter(el => el.display&& el.process === 1)"
                :key="j"
                :draggable="true"
                class="node-card f-r a-c j-b"
                @dragstart="onDrag($event, sub)"
              >
                <div class="node-name f-g">{{ sub.productName }}</div>
              </div>
            </div>
            <div class="">(可选)</div>
            <div class="content">
              <div
                v-for="(sub, j) in (item.productVoList || []).filter(el => el.display&& el.process === 2)"
                :key="j"
                :draggable="true"
                class="node-card f-r a-c j-b"
                @dragstart="onDrag($event, sub)"
              >
                <div class="node-name f-g">{{ sub.productName }}</div>
              </div>
            </div>
          </el-collapse-item>
        </el-collapse>
      </div>
      <div class="body f-g">
        <div class="canvas-header">
          <el-button color="primary" @click="save"> 保存 </el-button>
        </div>
        <div :id="domId" class="full" @contextmenu="onContextMenu($event)" />
      </div>
      <CanvasContextMenu
        v-show="contextmenu.left"
        :style="contextmenu"
        :context-menu-list="contextMenuList"
        @context="handleContext"
      />
    </div>
  </div>
</template>
<script>
import { createRandomId } from '@/plugins/canvas'
import CanvasContextMenu from './CanvasContextMenu'
import { Topology } from '@topology/core'
import { http_project_process_template } from '@/api'
import { setChildNode } from '@/utils/canvas'
// 配置项
const canvasOptions = {
  lineName: 'line',
  minScale: 0,
  maxScale: 50,
  // 连线颜色
  font: {
    color: '#fff',
    fontSize: 12
  },
  // 键盘事件 如 删除 移动
  keydown: -1,
  // 缩放 如 ctrl + mousewheel 缩放
  disableScale: true,
  // 移动 如 ctrl + mouse 移动
  disableTranslate: true,
  disableEmptyLine: false,
  autoAnchor: false,
  // autoExpandDistance: 0,
  cacheLen: 0,
  anchorFillStyleL: '#1976d2',
  dockFillStyle: '#1976d2',
  storkStyle: '#1976d2',
  hideInput: false
}
const stepMap = {
  1: '项目立项阶段',
  2: '规划许可阶段',
  3: '施工许可阶段',
  4: '竣工验收阶段'
}
export default {
  name: 'Canvas',
  components: {
    CanvasContextMenu
  },
  data() {
    return {
      templateId: '',
      category: '',
      subCategory: '',
      activeNames: [],
      Tools2: [
      ],
      Tools: [
        {
          id: 1,
          name: '项目立项阶段',
          productVoList: [
          ]
        },
        {
          id: 2,
          name: '规划许可阶段',
          children: []
        },
        {
          id: 3,
          name: '施工许可阶段',
          children: []
        },
        {
          id: 4,
          name: '竣工验收阶段',
          children: []
        }
      ],
      domId: createRandomId(),
      canvas: null,
      contextmenu: {
        left: null,
        top: null,
        bottom: null
      },
      nodeData: {
        data: {}
      },
      type: '',
      typeName: '',
      dialogId: ''
    }
  },
  computed: {
    contextMenuList() {
      return [
        {
          index: 'delete',
          name: '删除',
          line: false
        }
      ]
    }
  },
  async mounted() {
    const { category, subCategory } = this.$route.query
    this.category = category
    this.subCategory = subCategory
    this.initCanvas()
    // 节点 解析节点
    const nodeRes = await http_project_process_template.getNodesByCategory({
      bigCategoryId: category,
      smallCategoryId: subCategory,
      isMatter: 2
    })
    this.Tools = nodeRes.data.filter(el => el.stage < 5).map(el => {
      return {
        name: stepMap[el.stage],
        ...el,
        productVoList: el.productVoList.map(el2 => {
          return {
            display: true,
            text: el2.productName,
            rect: {
              width: 220,
              height: 90
            },
            name: 'rectangle',
            data: {
              type: 'node',
              ...el2
            },
            ...el2
          }
        })
      }
    })
    this.Tools2 = nodeRes.data.filter(el => el.stage === 5).map(el => {
      return {
        name: '标',
        ...el,
        productVoList: el.productVoList.map(el2 => {
          return {
            display: true,
            text: el2.productName,
            rect: { width: 50, height: 50 },
            name: 'circle',
            data: {
              type: 'node',
              ...el2
            },
            ...el2
          }
        })
      }
    })
    // 模版详情 存在打开canvas
    const templateRes = await http_project_process_template.read({
      bigCategoryId: category,
      smallCategoryId: subCategory
    })
    this.templateId = templateRes.data.mainTemplateId
    const { canvas, productList } = templateRes.data
    this.Tools.forEach(el => {
      el.productVoList.forEach(el2 => {
        if (productList.find(p => p.productCode === el2.productCode)) {
          el2.display = false
        }
      })
    })
    this.Tools2.forEach(el => {
      el.productVoList.forEach(el2 => {
        if (productList.find(p => p.productCode === el2.productCode)) {
          el2.display = false
        }
      })
    })
    if (!canvas) return
    if (typeof canvas !== 'string') return
    if (!canvas.includes('pens')) return
    // 打开画布
    this.canvas.open(canvas)
    setTimeout(() => {
      this.canvas.canvasPos = this.canvas.divLayer.canvas.getBoundingClientRect()
    })
  },
  beforeDestroy() {
    /**
     *  销毁画布
     */
    this.canvas.destroy()
    this.canvas = null
    document.onclick = null
  },
  methods: {
    onPageBack() {
      this.$router.replace({
        path: '/project/template'
      })
    },
    /**
     *  初始化画布
     */
    initCanvas() {
      this.canvas = null
      canvasOptions.on = this.onMessage
      this.canvas = new Topology(this.domId, canvasOptions)
      setTimeout(() => {
        // 修复鼠标框选错位
        this.canvas.data.lineName = 'polyline'
        this.canvas.data.toArrow = ''
        this.canvas.canvasPos = this.canvas.divLayer.canvas.getBoundingClientRect()
      }, 1000)
    },
    onMessage(event, data) {
      if (event === 'addNode') {
        if (data.name === 'text') {
          data.font.color = '#000'
        }
        if (data && data.data && data.data.type === 'node') {
          this.Tools.forEach(el => {
            el.productVoList.forEach(el2 => {
              if (el2.productCode === data.data.productCode) {
                el2.display = false
                console.log('0000')
                setChildNode(data, this.canvas)
              }
            })
          })
          this.Tools2.forEach(el => {
            el.productVoList.forEach(el2 => {
              if (el2.productCode === data.data.productCode) {
                el2.display = false
              }
            })
          })
        }
      }
      if (event === 'addLine') {
        data.strokeStyle = '#4880FF'
      }
      if (event === 'delete') {
        const nodeData = data[0] || {}
        if (nodeData && nodeData.type === 0 && nodeData.data && nodeData.data.type === 'node') {
          this.Tools.forEach(el => {
            el.productVoList.forEach(el2 => {
              if (el2.productCode === nodeData.data.productCode) {
                el2.display = true
              }
            })
          })
          this.Tools2.forEach(el => {
            el.productVoList.forEach(el2 => {
              if (el2.productCode === nodeData.data.productCode) {
                el2.display = true
              }
            })
          })
        }
      }
    },
    onDrag(event, node) {
      event.dataTransfer.setData(
        'Topology',
        JSON.stringify({
          name: node.name,
          text: node.text,
          rect: node.rect,
          data: node.data,
          fillStyle: '#4880FF',
          paddingLeft: 50,
          paddingRight: 30,
          paddingTop: 5,
          paddingBottom: 5,
          font: {
            color: '#fff'
          }
        })
      )
    },
    /**
     *  右击事件
     */
    onContextMenu(event) {
      event.preventDefault()
      event.stopPropagation()
      if (event.clientY + 360 < document.body.clientHeight) {
        this.contextmenu = {
          left: event.clientX + 'px',
          top: event.clientY + 'px'
        }
      } else {
        this.contextmenu = {
          left: event.clientX + 'px',
          bottom: document.body.clientHeight - event.clientY + 'px'
        }
      }
    },
    /**
     *  处理右击选择
     */
    handleContext(state) {
      this.canvas.delete()
      this.contextmenu = {
        left: null,
        top: null,
        bottom: null
      }
    },
    save() {
      const productVoList = []
      this.Tools.forEach(el => {
        el.productVoList.forEach(el2 => {
          if (!el2.display) {
            productVoList.push({
              productName: el2.productName,
              productCode: el2.productCode,
              isBidding: el2.isBidding,
              stage: el2.stage,
              process: el2.process
            })
          }
        })
      })
      http_project_process_template.updateCanvas({
        bigCategoryId: this.category,
        smallCategoryId: this.subCategory,
        mainTemplateId: this.templateId,
        canvas: JSON.stringify(this.canvas.data),
        productVoList
      }).then(res => {
        this.$message.success(res.msg)
        this.onPageBack()
      })
    },
    findNode(id) {
      return this.canvas.data.pens.find((el) => el.id === id) || {}
    },
    back() {
      this.$router.back()
    },
    saveForm({ key, data }) {
      this.nodeData.data[key] = data
    }
  }
}
</script>

<style scoped lang="scss">

.canvas-page {
  width: 100%;
  height: 100%;
  background-color: #F6F6F6;
}
.canvas {
  overflow: hidden;
  display: flex;
  background-color: #f2f2f2;
  padding: 10px;
  .menu {
    width: 300px;
    height: 100%;
    background-color: #fff;
    padding-left: 20px;
    overflow: auto;
    .item {
      width: 100%;
      .item-header {
        height: 40px;
        padding-left: 10px;
        line-height: 40px;
        border-bottom: 1px solid #666;
      }
    }
    .content {
      padding: 10px 20px 10px 0;
    }
    .icon-list {
      width: 100%;
      display: flex;
      flex-wrap: wrap;
      .icon-item {
        margin-right: 5px;
        &:hover {
          border: 1px solid #e2e2e2;
          border-radius: 3px;
        }
        cursor: pointer;
        width: 30%;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        img {
          width: 100%;
        }
      }
    }
  }
  .body {
    margin-left: 20px;
    position: relative;
    background-color: #ffffff;
    .canvas-header {
      position: absolute;
      right: 10px;
      top: 10px;
      z-index: 99;
    }
    .full {
      width: 100%;
      height: 100%;
      touch-action: none;
    }
  }
}
.menu-item {
  width: 60px;
  height: 60px;
  background-color: #4880FF;
  text-align: center;
  line-height: 60px;
  color: #ffffff;
  border-radius: 50%;
  cursor: pointer;
  margin-right: 10px;
  margin-bottom: 10px;
}
.node-card {
  cursor: pointer;
  width: 100%;
  height: 68px;
  background: #4880FF;
  border-radius: 8px 8px 8px 8px;
  opacity: 1;
  padding: 10px;
  margin-bottom: 13px;
  .node-name {
    user-select: none;
    font-size: 14px;
    line-height: 16px;
    text-align: center;
    padding-right: 10px;
    color: #ffffff;
  }
  .node-btn {
    height: 100%;
    i {
      color: #ffffff;
      font-size: 18px;
      cursor: pointer;
    }
  }
}
</style>
